package lol.clann.bukkit.pluginboot.util;

import lol.clann.clannboot.annotation.inject.Inject;
import lol.clann.clannboot.annotation.svc.PostInstance;
import lol.clann.clannboot.annotation.svc.Service;
import lol.clann.clannboot.util.clazz.ClassUtils;
import lol.clann.clannboot.util.clazz.WrapClass;
import lol.clann.clannboot.util.clazz.WrapMethod;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.command.CommandMap;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import org.slf4j.Logger;

import java.util.Collection;

/**
 * 提供了反影分身
 *
 * @author pyz
 * @date 2018/8/9 下午8:16
 */
@Service(priority = Integer.MAX_VALUE)
public class ServerUtils implements Listener {

    public static final WrapClass classCraftServer = ClassUtils.forName("{cb}.CraftServer");
    public static final WrapClass classNMSMinecraftServer = ClassUtils.forName("{nms}.MinecraftServer");

    private WrapMethod getServer;
    private WrapMethod getCommandMap;

    @Inject
    private Logger logger;
    @Inject
    private PlayerUtils playerUtils;
    @Inject
    private Server server;

    @PostInstance
    private void init() {
        getServer = classCraftServer.getMethod("getServer");
        getCommandMap = classCraftServer.getMethod("getCommandMap");
    }

    public CommandMap getCommandMap() {
        return (CommandMap) getCommandMap.invoke(server);
    }

    public Object getNMSServer() {
        return getServer.invoke(server);
    }

    public Server getServer() {
        return server;
    }

    public void sendPluginMessage(String channel, byte[] message) {
        sendPluginMessage(PluginUtils.getCallerPlugin(), channel, message);
    }

    public void sendPluginMessage(Plugin plugin, String channel, byte[] message) {
        server.sendPluginMessage(plugin, channel, message);
    }

    public void broadCase(String message) {
        Bukkit.broadcastMessage(message);
    }

    public void stop() {
        Bukkit.shutdown();
    }

    public void stop(String message) {
        Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "stop " + message);
    }

    public void notifyOp(String message) {
        for (Player player : getOnlinePlayers()) {
            if (playerUtils.isOp(player)) {
                player.sendMessage(message);
            }
        }
    }

    public int getLivingEntityCount() {
        int count = 0;
        for (World w : Bukkit.getWorlds()) {
            count += w.getLivingEntities().size();
        }
        return count;
    }

    public Collection<Player> getOnlinePlayers() {
        return (Collection<Player>) Bukkit.getOnlinePlayers();
    }

    public Player getPlayer(String name) {
        Player player = server.getPlayer(name);
        if (player == null || !player.getName().equals(name)) {
            return null;
        }
        return player;
    }

    public Player getPlayerIgnoreCase(String name) {
        Player player = server.getPlayer(name);
        if (player == null || !player.getName().equalsIgnoreCase(name)) {
            return null;
        }
        return player;
    }

    public OfflinePlayer getOfflinePlayer(String name) {
        OfflinePlayer player = server.getOfflinePlayer(name);
        if (player == null || !player.getName().equals(name)) {
            return null;
        }
        return player;
    }

    public OfflinePlayer getOfflinePlayerIgnoreCase(String name) {
        OfflinePlayer player = server.getOfflinePlayer(name);
        if (player == null || !player.getName().equalsIgnoreCase(name)) {
            return null;
        }
        return player;
    }
}
